package cms

import (
	"context"
	"errors"
	"gitcode.com/G-YT/baoyou/server/global"
	"gitcode.com/G-YT/baoyou/server/model/cms"
	"gitcode.com/G-YT/baoyou/server/utils"
)

type CategoryService struct{}

// CreateCategory 创建分类记录
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) CreateCategory(ctx context.Context, cat *cms.Category) (err error) {
	err = global.GVA_DB.Create(cat).Error
	return err
}

// DeleteCategory 删除分类记录
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) DeleteCategory(ctx context.Context, ID string) (err error) {
	var count int64
	err = global.GVA_DB.Find(&cms.Category{}, "parent_id = ?", ID).Count(&count).Error
	if count > 0 {
		return errors.New("此节点存在子节点不允许删除")
	}
	if err != nil {
		return err
	}
	err = global.GVA_DB.Delete(&cms.Category{}, "id = ?", ID).Error
	return err
}

// DeleteCategoryByIds 批量删除分类记录
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) DeleteCategoryByIds(ctx context.Context, IDs []string) (err error) {
	err = global.GVA_DB.Delete(&[]cms.Category{}, "id in ?", IDs).Error
	return err
}

// UpdateCategory 更新分类记录
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) UpdateCategory(ctx context.Context, cat cms.Category) (err error) {
	err = global.GVA_DB.Model(&cms.Category{}).Where("id = ?", cat.ID).Updates(&cat).Error
	return err
}

// GetCategory 根据ID获取分类记录
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) GetCategory(ctx context.Context, ID string) (cat cms.Category, err error) {
	err = global.GVA_DB.Where("id = ?", ID).First(&cat).Error
	return
}

// GetCategoryInfoList 分页获取分类记录,Tree模式下不添加分页和搜索
// Author [yourname](https://github.com/yourname)
func (catService *CategoryService) GetCategoryInfoList(ctx context.Context) (list []*cms.Category, err error) {
	// 创建db
	db := global.GVA_DB.Model(&cms.Category{})
	var cats []*cms.Category

	err = db.Find(&cats).Error

	return utils.BuildTree(cats), err
}
func (catService *CategoryService) GetCategoryPublic(ctx context.Context) {
	// 此方法为获取数据源定义的数据
	// 请自行实现
}

func (catService *CategoryService) GetCategoryDeep(ctx context.Context, cateID uint) (cates []cms.Category, err error) {
	// 1. 查询所有分类
	var all []cms.Category
	if err = global.GVA_DB.Find(&all).Error; err != nil {
		return nil, err
	}

	// 2. 构建 id -> *Category 映射
	m := make(map[uint]*cms.Category, len(all))
	for i := range all {
		// ensure Children is nil-initialized
		all[i].Children = nil
		m[all[i].ID] = &all[i]
	}

	// 3. 连接父子关系
	for i := range all {
		pid := uint(all[i].ParentID)
		if pid != 0 {
			if p, ok := m[pid]; ok {
				p.Children = append(p.Children, m[all[i].ID])
			}
		}
	}

	// 4. 查找指定根节点
	root, ok := m[cateID]
	if !ok || root == nil {
		return nil, errors.New("分类未找到")
	}

	// 5. 将树展平成平铺的切片（root + 所有递归子节点），返回值拷贝并清除 Children 字段
	var flat []cms.Category
	// 使用栈做 DFS，保持从父到子的顺序
	stack := []*cms.Category{root}
	for len(stack) > 0 {
		// pop
		n := stack[len(stack)-1]
		stack = stack[:len(stack)-1]

		// append value copy with Children cleared
		copyNode := *n
		copyNode.Children = nil
		flat = append(flat, copyNode)

		// push children in reverse order so they are processed in original order
		for i := len(n.Children) - 1; i >= 0; i-- {
			stack = append(stack, n.Children[i])
		}
	}

	return flat, nil
}
